/**
 * Created by L.jp
 * Description:
 * User: 86189
 * Date: 2022-02-13
 * Time: 17:52
 */
public class Solution2 {
    //递归版本：以1->2->3->4->5->null为例,分为两个问题，翻转头节点，翻转头节点之后的节点
    //这个 reverse(head.next) 执⾏完成后，整体要实现的效果，整个链表就成了这样：
    //1->2<-3<-4<-5,此时新的头结点是5，而执行完这个递归函数之后2.next应该是==null的，因为1是第一个head，所以要翻转它很简单
    //head.next.next=head;//这就改变了指向
    //然后因为原来还有1->2，所以需要把这个指向切空，也就是只要1<-2了
    //我们再把这个方法落实到每一个节点就是整体的递归翻转链表

   /* 第一轮出栈，head为5，head.next为空，返回5
    第二轮出栈，head为4，head.next为5，执行head.next.next=head也就是5.next=4，
    //返回之后，就会执行递归函数后面的代码，也就是 head.next.next=head;head.next=null;head.next为空了，所以又会进入if语句，又会不断返回head,依次类推
    把当前节点的子节点的子节点指向当前节点
    此时链表为1->2->3->4<->5，由于4与5互相指向，所以此处要断开4.next=null
    此时链表为1->2->3->4<-5
    返回节点5
    第三轮出栈，head为3，head.next为4，执行head.next.next=head也就是4.next=3，
    此时链表为1->2->3<->4<-5，由于3与4互相指向，所以此处要断开3.next=null
    此时链表为1->2->3<-4<-5
    返回节点5
    第四轮出栈，head为2，head.next为3，执行head.next.next=head也就是3.next=2，
    此时链表为1->2<->3<-4<-5，由于2与3互相指向，所以此处要断开2.next=null
    此时链表为1->2<-3<-4<-5
    返回节点5
    第五轮出栈，head为1，head.next为2，执行head.next.next=head也就是2.next=1，
    此时链表为1<->2<-3<-4<-5，由于1与2互相指向，所以此处要断开1.next=null
    此时链表为1<-2<-3<-4<-5
    返回节点5
    出栈完成，最终头节点5->4->3->2->1*/

    public ListNode reverseList(ListNode head) {
        //递归问题需要把大问题看成两部分，第一个部分往往是第一个东西，第二个部分就是第一个部分后面整体的部分
        //之后第二个部分里面有划分为两个部分，依次类推到最后就变成了一个东西
        //我们解决递归问题，不妨先假设出第一个东西的后面的部分已经完成了递归函数实现的效果，这样我们既然已经知道了后面部分实现
        //的效果，那么我们就可以只想第一个东西要怎么实现这个递归函数的效果，因为第一个东西跟后面部分在递归函数里是一样实现的
        //所以只要想出第一个部分是怎么实现的就可以了
        //以这个翻转链表为例：我们知道翻转链表后，第二个部分递归函数实现的应该是：1->2<-3<-4<-5，也就是只把第一个后面的部分反转了
        //只剩下第一个节点没有反转，那么第一个节点应该怎么反转：
        //我们知道第一个结点是head,head.next=2,那么要翻转他俩，就是head.next.next=head;
        // 但是之后别别忘了把原来的head.next给置空，这样才保证了单向的链表，完成了逆置
        //最后返回新的头节点就可以了，新的头节点在每一次递归函数执行的时候都会返回一个节点，递的过程执行完就找到了新的头节点


        //递归出口
        if(head==null || head.next==null){
            return  head;
        }
        //递归，直到找到最后一个节点作为新的头节点
       ListNode newHead= reverseList(head.next);
        //归实现的细节
        head.next.next=head;//改变原来指向  //head依次是5,4,3,2,1，head是5时相当于没有改变指向，是自己指向自己
        head.next=null;//把原来的指向置空
        return newHead;
    }
}
